package com.deke.security.aspect;

import cn.hutool.core.util.ObjectUtil;
import com.deke.security.annotation.RequiresPermission;
import com.deke.security.exception.PermissionException;
import com.deke.security.utils.WebUtils;
import com.deke.utils.JwtTool;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * @author ：Username 刘亦辰（59372312@qq.com）
 * @date ：Created in 2022/12/2 17:30
 * @description：  判断是否具有权限
 * @modified By：
 * @version:
 **/
@Component
//标记为切面类
@Aspect
public class PreAuthorizeAspact {

    //切点: 在哪些位置上添加我们的aop切面
    @Pointcut(value = "@annotation(com.deke.security.annotation.RequiresPermission)")
    public  void  pointcut(){}

    //环绕通知
    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint joinPoint){
        //获取连接点的方法  获取哪些方法使用了RequiresPermission
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //获取方法上的RequiresPermission
        CheckAnnotation(methodSignature.getMethod());
        //回调方法
        Object result   = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }

    private void CheckAnnotation(Method method){
        RequiresPermission requiresPermission = method.getAnnotation(RequiresPermission.class);
        if (ObjectUtil.isNotNull(requiresPermission)){
            String value = requiresPermission.value();
            HttpServletRequest request = WebUtils.getRequest();
            String token = request.getHeader("token");
            Map<String, Object> tokenClaim = JwtTool.getTokenClaim(token);
            List<String> permissions = (List<String>) tokenClaim.get("permissions");
            if (!permissions.contains(value)){
                throw new PermissionException("权限不足");
            }
        }
    }
}